using System;
using System.Linq;
using ENodeMicro.Common;
using Grpc.Net.Client;
using NConsul;

namespace ENodeMicro.WebAPI
{
    public static class GRpcClient
    {
        /// <summary>
        /// 读取实例
        /// </summary>
        /// <param name="channel"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetInstance<T>(this GrpcChannel channel)
        {
            return (T)Activator.CreateInstance(typeof(T), channel);
        }
        
        /// <summary>
        /// 读取GRpc通道
        /// </summary>
        /// <param name="serviceName">服务名称</param>
        /// <returns></returns>
        public static GrpcChannel GetGRpcChannel(string serviceName)
        {
            var address = GetServiceAddress(serviceName);
            return GrpcChannel.ForAddress(address);
        }
        
        /// <summary>
        /// 从Consul中读取服务地址
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private static string GetServiceAddress(string serviceName)
        {
            try
            {
                var consulClient = new ConsulClient(config =>
                {
                    config.Address = new Uri(ConfigSettings.ConsulAddress);
                });
                var gRpcServices = consulClient.Catalog.Service(serviceName).Result;
                if (gRpcServices.Response.Length == 0)
                {
                    throw new Exception($"未发现服务，服务名({serviceName})");
                }
                //客户端负载均衡，随机选出一台服务
                var rand = new Random();
                var index = rand.Next(gRpcServices.Response.Length);
                var service = gRpcServices.Response.ElementAt(index);
                return $"{ConfigSettings.GRpcHttpScheme}://{service.ServiceAddress}:{service.ServicePort}";
            }
            catch (Exception ex)
            {
                throw new Exception($"读取服务地址异常，异常信息：{ex.Message}");
            }
        }
    }
}